/*
	transfer.js
	by morriswmz
*/


// global variables
var bg = chrome.extension.getBackgroundPage();
var lsManager = lsManager || bg.lsManager;
var localDB = localDB || bg.localDB;


var pending_search; // indicating current search
var state = 0;  // 0 - welcom
				// 1 - search
				// 2 - no result
var direct_go = 0; // hit enter
var list_limit = 10; // max number of items in result list
var recent_limit = 5; // max number of items in recent list
var last_keyword;


// utils
function shorter_time(tnd) {
	var res = tnd.replace(/&nbsp;/g,' ');
	res = res.replace(/ +/g,' ');
	res = res.replace(/时间：/g,'');
	res = res.replace(/年|月|日/g,'/');
	res = res.replace(/到/g,'~');
	res = res.replace(/ \/|\/ /,'/');
	return res;
}

function cut_string(str, max) {
	return (str.length>max) ? str.substring(0,max-1)+'...' : str; 
}

function nicer_time(timeint) {
	var s = timeint/1000;
	if (s < 60) {
		return Math.round(s)+'秒';
	} else if (s < 3600) {
		return Math.round(s/60)+'分钟';
	} else if (s < 86400) {
		return Math.round(s/3600)+'小时';
	} else {
		return Math.round(s/86400)+'天';
	}
}

// state manager object
var states = (function () {
	var curState = 0;
	var con_welcome, con_list, con_info;
	var info_emotion, info_text;
	var states = {
		init : function () {
			// set up quick references
			con_welcome = jQuery('#welcome');
			con_list = jQuery('#search_list');
			con_info = jQuery('#noresult');
			info_emotion = jQuery('#noresult h2');
			info_text = jQuery('#noresult p');
			curState = 0;
		},
		
		// goto welcome state
		welcome : function () {
			curState = 0;
			con_welcome.removeClass('hide');
			con_list.addClass('hide');
			con_info.addClass('hide');
			
		},
		
		// display list
		list : function () {
			curState = 1;
			con_welcome.addClass('hide');
			con_list.removeClass('hide');
			con_info.addClass('hide');
		},
		
		// display info
		info : function (err) {
			curState = 2;
			var emo = ':(', msg = '没有找到结果，试试别的吧';
			if (err) {
				switch (err) {
					case 'net':
						emo = '</>';
						msg = '连接不上服务器，没法获得信息了';
						break;	
					default:
						emo = '._.';
						msg = '出错了：'+err;
				}
			}
			info_emotion.text(emo);
			info_text.text(msg);
			con_welcome.addClass('hide');
			con_list.addClass('hide');
			con_info.removeClass('hide');
		}
	};
	return states;
})();

// check and extract prefix from keyword string
function check_prefix(keyword) {
	var result = {prefix:"", keywords:[]};
	var str = keyword.toLowerCase();
	var matches = str.match(/-([^ ]+)(.*)/);
	if (matches && matches[1]) {
		matches[2]= matches[2].replace(/^ +/, '');
		//alert(matches.join(','));
		result.prefix = matches[1];
		result.keywords = matches[2];
	} else {
		result.keywords = str;
		//alert(result.keywords.length);
	}
	return result;
}

// omni search
function t_search(keyword) {
	if (!keyword) {
		write_search_result([]);
	}
	var result = [];
	var pre = check_prefix(keyword);
	var url;
	switch (pre.prefix) {
		case '10':
		case 'sd':
			search_ajax('http://bbs.fudan.edu.cn/bbs/top10', dp_top10);
			break;
		case 'jz':
		case 'lec':
			search_ajax('http://stu.fudan.edu.cn/lecture/default.aspx', dp_lecture);
			break;
		case 'hd':
		case 'event':
			search_ajax('http://stu.fudan.edu.cn/event/Home/Filter?page=0&count=10&keyword='
			+ escape(pre.keywords) + '&date=all&tag=all&option=', dp_event);
			break;
		case 'r':
			search_tabs(pre.keywords);
			break;
		case 'help':
		case 'bz':
			direct_go = 0;
			write_search_result(localDB.help_db);
			break;
		default:
			search_local(pre.keywords);
	}
}

// default search function
// search local database and stu transfer and return sorted list
function search_local(keyword) {
	if (!keyword) {
		write_search_result([]);
	}
	var keywords = keyword.split(/ +/);
	var num_keywords = keyword.length;
	var priority;
	var current_entry;
	var sub_index;
	var result = [];
	var num_result = 0;
	var transfer_db = localDB.transferDB;
	var db_length = transfer_db.length;
	for (var i=0;i<db_length && num_result < list_limit;i++) {
		priority = 0;
		current_entry = transfer_db[i];
		for (var j=0;j<num_keywords;j++) {
			sub_index = current_entry.title.indexOf(keywords[j]); 
			if (sub_index != -1) {
				priority += 16 - sub_index;
			}
			sub_index = current_entry.pyshort.indexOf(keywords[j]); 
			if (sub_index != -1) {
				priority += 16 - sub_index;
			}
			sub_index = current_entry.url.indexOf(keywords[j]); 
			if (sub_index != -1) {
				priority += 3;
			}
		}
		if (priority > 0) {
			result.push({title:current_entry.title, url:current_entry.url, ranking: priority});
			num_result++;
		}
	}
	if (result.length > 0) {
		result.sort(function (a, b) {
			return b.ranking - a.ranking;
		});
		write_search_result(result);
	} else {
		search_ajax('http://stu.fudan.edu.cn/transfer/Result.aspx?target='+escape(keyword), dp_transfer);
	}
}

/*  search online using ajax
	------------------------
		- request_url : URL of request
		- data_parser : function that parses the received data and generate result list
		- cache_id : identifier for local storage
*/
function search_ajax(request_url, data_parser, alternative, cache_id) {
	jQuery.get(request_url, function (data, textStatus, xhr) {
		if (xhr.status == '200') {
			write_search_result(data_parser(data));
		} else {
			write_search_result([], xhr.status);
		}
	}).fail(function () {
		write_search_result([], 'net');
	});
}

// search for closed tabs
function search_tabs(keyword) {
	var closed_tabs = bg.tabRecorder.getClosedTabList();
	var current_entry;
	var result = [];
	var now = (new Date()).getTime();
	for (var i=0;i<closed_tabs.length;i++) {
		current_entry = closed_tabs[i]; 
		if (current_entry.title.toLowerCase().indexOf(keyword) != -1) {
			result.push({
				title: current_entry.title,
				url: current_entry.url,
				additional : '[' + nicer_time(now-current_entry.time) + '前]  ' + current_entry.url
			});
			if (result.length == list_limit) {
				break;
			}
		}
	}
	write_search_result(result);
}

// data parsers
// stu transfer
function dp_transfer(data) {
	var matches = data.match(/<span class=sitename>(.*?)<\/span>.+?<br \/>(.*?)<\/p>/g);
	var result = [];
	if (matches) {
		for (var i=0;i<matches.length;i++) {
			var tmp = matches[i].match(/<span class=sitename>(.*?)<\/span>.+?<br \/>(.*?)<\/p>/);
			result.push({title:tmp[1], url:tmp[2], ranking: i});
		}
	}
	return result;
}

// bbs top10 parser
function dp_top10(data) {
	var matches = data.getElementsByTagName('top');
	var result = [];
	var tmp_url, tmp_title, tmp_add;
	if (matches) {
		for (var i=0;i<matches.length;i++) {
			tmp_url = 'http://bbs.fudan.edu.cn/bbs/tcon?new=1&board=' + 
						matches[i].getAttribute('board') + '&f=' +
						matches[i].getAttribute('gid');
			tmp_title = matches[i].childNodes[0].nodeValue;
			tmp_add = '作者：' + matches[i].getAttribute('owner') +
						' 版面：' + matches[i].getAttribute('board') +
						' 篇数：' + matches[i].getAttribute('count');
			result.push({
				title:tmp_title,
				url:tmp_url,
				ranking: i,
				additional: tmp_add
			});
		}
	}
	return result;
}

// stu lecture parser
function dp_lecture(data) {
	var m_tl = data.match(/><\/div><div>.*?<\/div><div>.*?<\/div>/g);
	var m_title = data.match(/class="card_title".*?</g);
	var m_lecturer = data.match(/class="card_speaker".*?<\/a/g);
	var result = [];
	var cur_div;
	var tmp_title, tmp_lecturer, tmp_time, tmp_url;
	if (m_tl && m_title && m_lecturer) {
		for (var i=0;i<m_tl.length;i++) {
			tmp_title = m_title[i].match(/>(.*)</)[1];
			tmp_url = m_title[i].match(/href="(.*)"/)[1];
			tmp_lecturer = m_lecturer[i].match(/">(.*?)</)[1];
			tmp_time = m_tl[i].match(/<div>(.+?)</)[1];
			result.push({
				title:tmp_title,
				url:'http://stu.fudan.edu.cn' + tmp_url,
				ranking: i,
				additional: '主讲人：' + tmp_lecturer + ' ' + tmp_time
			});
		}
	}
	return result;
}

// stu event parser
function dp_event(data) {
	var matches = data.match(/h4>[^^]+?<\/div/g);
	var result = [];
	var cur_div;
	var tmp_title, tmp_type, tmp_lt, tmp_time, tmp_loc, tmp_url;
	if (matches) {
		for (var i=0;i<matches.length;i++) {
			tmp_type = matches[i].match(/">(.*?)<\/small/)[1];
			tmp_title = matches[i].match(/<small.*>(.*)<\/a/)[1];
			tmp_url = matches[i].match(/href="(.*)"/)[1];
			tmp_lt = matches[i].match(/<p>(.*?)<\/p>/g);
			tmp_time = tmp_lt[0].match(/>(.*)</)[1];
			tmp_loc = tmp_lt[1].match(/>(.*)</)[1];
			result.push({
				title: tmp_type + tmp_title,
				url:'http://stu.fudan.edu.cn' + tmp_url,
				ranking: i,
				additional: shorter_time(tmp_time) + ' ' +
							tmp_loc.substring(3)
			});
		}
	}
	return result;
}

// search library

// open new tab and save recent
function follow_link(container) {
	var a_tmp = container.find('a');
	var url_tmp = a_tmp.attr('href');
	if (url_tmp.length > 0) {
		save_recent({title:a_tmp.text(), url:url_tmp, ranking:0});
		chrome.tabs.create({url:a_tmp.attr('href')});
	}
}

// create single list
function create_single_list(info, container) {
	// substr
	var t_title = cut_string(info.title, 20);
	var t_url = cut_string(info.url, 50);
	var t_add = info.additional && cut_string(info.additional, 50);
	// createElement
	var a_tmp = jQuery(document.createElement('a'));
	a_tmp.text(t_title);
	a_tmp.attr('title',info.title);
	a_tmp.attr('href',info.url);
	var p_tmp = jQuery(document.createElement('p'));
	if (info.additional) {
		p_tmp.text(t_add);
	} else {
		p_tmp.text(t_url);
	}
	var li_tmp = jQuery(document.createElement('li'));
	li_tmp.append(a_tmp);
	li_tmp.append(p_tmp);
	container.append(li_tmp);
}

// generate list
function write_search_result(result, err) {
	if (result.length == 0) {
		// if no result, go to noresult state
		direct_go = 0;
		states.info(err);
	} else {
		// go to result state
		if (states.curState != 1) {
			states.list();
		}
	}
	// if user hits enter, directly navigate to the 1st result
	if (direct_go == 1) {
		save_recent({title:result[0].title, url:result[0].url, ranking:0});
		chrome.tabs.create({url:result[0].url});
		return;
	}
	// get result list container
	var container = jQuery('#search_list ul');
	// clear last list
	container.empty();
	// generate list
	for (var i=0;i<result.length&&i<list_limit;i++) {
		create_single_list(result[i], container);
	}
	// add animation and bind event handler
	jQuery('#search_list li').each(function (index) {
		jQuery(this).css({opacity:0.0, 'margin-left':-5});
		jQuery(this).delay(index*20).animate({opacity:1.0, 'margin-left':0}, 150);
		jQuery(this).bind('click', function () {
			follow_link($(this));
		});
	});
}

// update when search_box is changed
function update_search_result() {
	var cur_keyword = jQuery("#search_box").attr('value');
	if (cur_keyword != last_keyword) {
		last_keyword = cur_keyword;
		t_search(cur_keyword);
		window.setTimeout(function () { last_keyword = ''; }, 1000);
		window.clearTimeout(pending_search);
	}
}

// reset recent
function reset_recent() {
	lsManager.save('recentNum', 0);
	lsManager.save('recentList', []);
}

// save last transfer
function save_recent(transfer) {
	var num;
	if (lsManager.exist('recentNum')) {
		num = Number(lsManager.get('recentNum'));
		lsManager.save('recentNum', Math.min(recent_limit, num+1));
		lsManager.updateList('recentList', transfer, 'title', recent_limit);
	} else {
		lsManager.save('recentNum', 0);
	}
}

// generate recent list
function write_recent_list() {
	var list = lsManager.get('recentList', true);
	var container = jQuery('#recent_list');
	container.empty();
	// if nothing inside, hide title
	if (list.length == 0) {
		jQuery('#welcome h3').css('display','none');
		return;
	}
	// show title
	jQuery('#welcome h3').css('display','block');
	// generate recent list
	for (var i=0;i<list.length;i++) {
		var a_tmp = $(document.createElement('a'));
		a_tmp.text(cut_string(list[i].title, 18));
		a_tmp.attr('href',list[i].url);
		container.append(a_tmp);
		a_tmp.wrap('<li></li>');
	}
	// bind event handler for them
	jQuery('#recent_list li').bind('click', function () {
		follow_link($(this));
	});
}

// event handlers using jQuery
jQuery(document).ready(function () {
	// initialize state manager
	states.init();

	// auto focus on searchbox
	jQuery("#search_box").focus();
	
	// instant update when user type a letter
	jQuery("#search_box").keyup(function (e) {
		// clear pending search and assign a new one
		// avoid update too frequently
		if (e.which == 13) {
			direct_go = 1;
		}
		if (pending_search) {
			window.clearTimeout(pending_search);
		}
		if (jQuery(this).attr('value')) {
			// something in searchbox! assign a new search task
			pending_search = window.setTimeout(update_search_result, 500);
		} else {
			// nothing in searchbox, then go to welcome state
			states.welcome();
		}
	});
	
	// clear searchbox button event handler
	jQuery('#clear_btn').click(function () {
		state = 0;
		// cleanup and go back to welcome state
		jQuery('#search_box').val('');
		jQuery('#search_list ul').empty();
		jQuery('#noresult').addClass('hide');
		jQuery('#welcome').removeClass('hide');
		jQuery('#search_list').addClass('hide');
	});
	

	// clear recent button event handler
	jQuery('#clear_recent').click(function () {
		reset_recent();
		// add some nice fading effect
		$('#welcome h3').animate({opacity:0.0}, 500);
		$('#recent_list').animate({opacity:0.0}, 500, function (){
			write_recent_list();
			$('#welcome recent_list').css({opacity:1.0});
		});
	});
	
	//show recent
	window.setTimeout(write_recent_list,200);
	// test ajax
	
});